package cube.utils;

import static java.util.Collections.list;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import cube.io.StreamUtil;

/**
 * 网络工具
 * 
 * @author abiao
 */
public class NetUtil {

    /**
     * 本地IP地址信息
     */
    private static Map<String, String> localIPs;

    /**
     * 初始化本地IP地址信息
     */
    static {
        initLocalIPs();
    }

    /**
     * 获取本地IP地址列表
     */
    public static String[] getLocalIPs() {
        return localIPs.values().toArray(new String[localIPs.size()]);
    }

    /**
     * 获取本地网络设备列表
     */
    public static Set<String> getLocalDevs() {
        return localIPs.keySet();
    }

    /**
     * 根据设备名获取本地IP地址
     */
    public static String getLocalIP(String dev) {
        return localIPs.get(dev);
    }

    /**
     * 获取所有网络接口
     */
    private static Enumeration<NetworkInterface> getNetInterfaces() {
        Enumeration<NetworkInterface> nis = null;
        try {
            nis = NetworkInterface.getNetworkInterfaces();
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return nis;
    }

    /**
     * 是否为IPV4类型的地址
     */
    public static boolean isIPV4(String ip) {
        return ip.matches("[0-9]+.[0-9]+.[0-9]+.[0-9]+");
    }

    public static boolean isLOs(String ip) {
        return "127.0.0.1".equals(ip) || "127.1".equals(ip);
    }

    /**
     * 初始化本地IP地址信息
     */
    private static void initLocalIPs() {
        localIPs = new HashMap<String, String>();
        for (NetworkInterface ni : list(getNetInterfaces())) {
            for (InetAddress ia : list(ni.getInetAddresses())) {
                String ip = ia.getHostAddress();
                if (isIPV4(ip) && !isLOs(ip)) {
                    localIPs.put(ni.getName(), ia.getHostAddress());
                }
            }
        }
    }

    /**
     * mac地址转为byte数组
     */
    public static byte[] mac2bytes(String mac) {
        String[] macs = getMacs(mac);
        if (macs == null || macs.length != 6) {
            return null;
        }
        byte[] macBytes = new byte[6];
        for (int i = 0; i < macBytes.length; i++) {
            macBytes[i] = (byte) Integer.parseInt(macs[i], 16);
        }
        return macBytes;
    }

    /**
     * 分割mac地址
     */
    private static String[] getMacs(String mac) {
        String[] macs = null;
        if (mac.contains(":")) {
            macs = mac.split(":");
        } else if (mac.length() == 12) {
            macs = new String[6];
            for (int i = 0; i < macs.length; i++) {
                macs[i] = mac.substring(i * 2, (i + 1) * 2);
            }
        }
        return macs;
    }

    /**
     * 检查端口是否可用
     */
    public static boolean isPortAvailable(int port) {
        Socket sk = null;
        try {
            sk = new Socket("127.0.0.1", port);
        } catch (Exception e) {
            return true;
        } finally {
            StreamUtil.close(sk);
        }
        return false;
    }
}
